import {
    JSEncrypt
} from 'jsencrypt';
import pako from 'pako';
import Layout from "@/views/layout/Layout";
import AppMain from "@/views/layout/components/AppMain";
import CryptoJS from 'crypto-js'
const util = {
    //把后台传得扁平化JSON格式转化为EasyUI Tree树控件的JSON格式 rows:json数据对象;idFieldName:表id的字段名;pidFieldName:表父级id的字段名;fileds:要显示的字段,多个字段用逗号分隔
    toTreeData: function (rows, id, parentid, fileds) {
        function exists(rows, ParentId) {
            for (let i = 0; i < rows.length; i++) {
                if (rows[i][id] == ParentId)
                    return true;
            }
            return false;
        }
        let nodes = [];

        for (let i in rows) {
            let row = rows[i];
            if (!exists(rows, row[parentid])) {
                //let data = {
                //    id: row[id]
                //}
                let data = {};
                data[id] = row[id];
                let arrFiled = fileds.split(",");
                for (let j = 0; j < arrFiled.length; j++) {
                    let arrF = arrFiled[j].split("|");
                    if (arrF[0] != id)
                        data[arrF[0]] = row[arrF[0]];
                    if (arrF[1] && arrF[1] != id)
                        data[arrF[1]] = row[arrF[0]];
                }
                nodes.push(data);
            }
        }
        let toDo = [];
        for (let i = 0; i < nodes.length; i++) {
            toDo.push(nodes[i]);
        }
        while (toDo.length) {
            let node = toDo.shift(); // the parent node
            // get the children nodes
            for (let i = 0; i < rows.length; i++) {
                let row = rows[i];
                if (row[parentid] == node[id]) {
                    //let child = {
                    //    id: row[id]
                    //};
                    let child = {};
                    child[id] = row[id];
                    let arrFiled = fileds.split(",");
                    for (let j = 0; j < arrFiled.length; j++) {
                        let arrF = arrFiled[j].split("|");
                        if (arrF[0] != id)
                            child[arrF[0]] = row[arrF[0]];
                        if (arrF[1] && arrF[1] != id)
                            child[arrF[1]] = row[arrF[0]];
                    }
                    if (node.children) {
                        node.children.push(child);
                    } else {
                        node.children = [child];
                    }
                    toDo.push(child);
                }
            }
        }
        return nodes;
    },
    encrypt: function (val) {
        let encrypt = new JSEncrypt();
        encrypt.setPublicKey("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+K3y4fL71dFhFYC9c9bea9wPH" + "\r" +
            "youU86VI0nI1GtDiMbSd3/mFcf/Z14hixordW8W8Q0BftncjcbIOHOeHDK074hpV" + "\r" +
            "bMdJTgadisuksX1fISp5CXa5ETsDcHa6usb1wGd2EFSo8ws5Jfi5oGZVgRzF3YLI" + "\r" +
            "KgxYn+NZu7cvHOD0GwIDAQAB" + "\r");
        let data = encrypt.encrypt(val);
        return data;
    },
    //替换url.-+
    replaceD: function (str) {
        var len = str.split(".").length + 1;
        for (var i = 0; i < len; i++) {
            str = str.replace(".", "%2E");
        }
        var len = str.split("-").length + 1;
        for (var i = 0; i < len; i++) {
            str = str.replace("-", "%2D");
        }
        var len = str.split("+").length + 1;
        for (var i = 0; i < len; i++) {
            str = str.replace("+", "%2B");
        }
        var len = str.split("/").length + 1;
        for (var i = 0; i < len; i++) {
            str = str.replace("/", "%2F");
        }
        var len = str.split("=").length + 1;
        for (var i = 0; i < len; i++) {
            str = str.replace("=", "%3D");
        }
        return str;
    },
    getApiUrl() {
        let src;
        if (process.env.NODE_ENV == 'development') { //开发环境 
            src = process.env.VUE_APP_DEVBASEURL;
        } else if (process.env.NODE_ENV == 'debug') { //测试环境
            src = process.env.VUE_APP_DEBBASEURL;
        } else if (process.env.NODE_ENV == 'production') { //生产环境
            src = process.env.VUE_APP_PROBASEURL;
        }
        return src;
    },
    getFile() {
        let url = window.location.href;
        if (url.indexOf("/" + process.env.VUE_APP_APPCODE) > -1)
            url = url.split("/" + process.env.VUE_APP_APPCODE)[0] + process.env.VUE_APP_APPCODE;
        else if (url.indexOf("/#/") > -1)
            url = url.split("/#/")[0] + '/' + process.env.VUE_APP_APPCODE;
        return url;
    },
    getLocalUrl() {
        var winurl = window.location.href;
        var url = winurl.substring(0, winurl.match("/#/").index);
        return url;
    },
    fileDownload(id) {
        window.open(util.getApiUrl() + "/sys/file/download?id=" + id, "_blank");
    },
    fileOpen(id) {
        window.open(util.getApiUrl() + "/sys/file/open?id=" + id, "_blank");
    },
    windowOpen(url) {
        window.open(util.getFile() + url, "_blank");
    },
    getRoutesP(data, li) {
        let rs = [];
        for (let i in data) {
            if (data[i].type == "访问路径") {
                if (!data[i].url) {
                    let urlp = data[i].children[0].url;
                    urlp = urlp.substring(4, urlp.length - 5).split("/");
                    data[i].url = "/" + urlp[1];
                } else {
                    data[i].url = data[i].url.substring(4, data[i].url.length - 5);
                }
                let array = data[i].url.split('/');
                let name = array[array.length - 1];
                let route = {
                    path: data[i].url,
                    meta: {
                        title: data[i].description,
                        icon: data[i].icon ? data[i].icon.trim() : ""
                    },
                    component: resolve => require([`@/views${data[i].url}`], resolve)
                };
                if (data[i].children) {
                    route.component = Layout;
                    route.name = name;
                    let re = data[i].children[0].url;
                    re = re.substring(4, re.length - 5);
                    route.redirect = re;
                    route.children = util.getRoutesP([...data[i].children], li + 1);
                } else {
                    route.name = name;
                    if (data[i].menuLevel == 100) route.hidden = true;
                }
                rs.push(route);
            }
        }
        return rs;
    },
    getRoutes(data, li) {
        let rs = [];
        for (let i in data) {
            if (data[i].permissionType !== "BUTTON") {
                let array = data[i].url.split('/');
                let name = array[array.length - 1];
                let route = {
                    path: data[i].url,
                    meta: {
                        title: data[i].description,
                        icon: data[i].icon ? data[i].icon.trim() : ""
                    },
                    component: resolve => require([`@/views${data[i].url}`], resolve)
                };
                if (data[i].children) {
                    if (data[i].menuLevel == 1) {
                        route.component = Layout;
                    } else {
                        route.component = AppMain;
                    }
                    route.name = name;
                    route.redirect = data[i].children[0].url;
                    route.children = util.getRoutes([...data[i].children], li + 1);
                } else {
                    if (data[i].menuLevel == 1) {
                        route.path = '';
                        route.redirect = data[i].url;
                        route.component = Layout;
                        route.children = [];
                        let routei = {};
                        routei.path = data[i].url; //name
                        routei.name = name;
                        routei.meta = {
                                title: data[i].description,
                                icon: data[i].icon ? data[i].icon.trim() : ""
                            },
                            routei.component = resolve => require([`@/views/${data[i].url}`], resolve); //name
                        route.children.push(routei);
                    } else {
                        // let ar = [];
                        // for (let j = li; j < array.length; j++) {
                        //     ar.push(array[j]);
                        // }                      
                        // route.path = ar.join("/");
                        route.name = name;
                        if (data[i].menuLevel == 100) route.hidden = true;
                    }
                }
                rs.push(route);
            }
        }
        return rs;
    },
    getQueryString(href) {
        let qs = {};
        let url = href || decodeURIComponent(window.location.href);
        //不管有没有伪静态 都看一下?问号后面的参数
        if (url.indexOf('?') > -1) {
            url = url.substring(url.indexOf('?') + 1);
            let prm = url.split('&');
            for (let p in prm) {
                if (prm[p]) {
                    let sp = prm[p].split('=');
                    if (sp.length > 1) {
                        let spkey = sp[0];
                        let spvalue = sp[1];

                        if (spvalue.indexOf('#') > -1) {
                            spvalue = spvalue.substring(0, spvalue.indexOf('#'));
                        }
                        qs[spkey] = spvalue;
                    }
                }
            }
        }
        return qs;
    },
    unGzip(data) {
        console.log("data", data);
        var strData = window.atob(data);
        // Convert binary string to character-number array
        var charData = strData.split('').map(function (x) {
            return x.charCodeAt(0);
        });
        // Turn number array into byte-array
        var binData = new Uint8Array(charData);
        // // unzip
        var data = pako.inflate(binData);
        // Convert gunzipped byteArray back to ascii string:
        // strData   = String.fromCharCode.apply(null, new Uint16Array(data));
        var array = new Uint16Array(data)
        var res = '';
        var chunk = 8 * 1024;
        var i;
        for (i = 0; i < array.length / chunk; i++) {
            res += String.fromCharCode.apply(null, array.slice(i * chunk, (i + 1) * chunk));
        }
        res += String.fromCharCode.apply(null, array.slice(i * chunk));
        strData = unescape(res);
        return strData;
    },
    toUrl(url, data) {
        let tourl = url;
        for (let i in data) {
            if (tourl.indexOf('?') > -1)
                tourl += '&' + i + '=' + data[i];
            else
                tourl += '?' + i + '=' + data[i];
        }
        return tourl;
    },
    mapNumberUtil: {
        rad: function rad(d) {
            return d * Math.PI / 18;
        },
        deg: function deg(d) {
            return d * 180 / Math.PI
        }
    },
    getLngLat(lng, lat, brng, dist) {
        //大地坐标系资料WGS-84 长半径a=6378137 短半径b=6356752.3142 扁率f=1/298.2572236正北方：000°或360° 正东方：090° 正南方：180° 正西方：270°
        var a = 6378137;
        var b = 6356752.3142;
        var f = 1 / 298.257223563;

        var lon1 = lng * 1;
        var lat1 = lat * 1;
        var s = dist;
        var alpha1 = util.mapNumberUtil.rad(brng);
        var sinAlpha1 = Math.sin(alpha1);
        var cosAlpha1 = Math.cos(alpha1);

        var tanU1 = (1 - f) * Math.tan(util.mapNumberUtil.rad(lat1));
        var cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)),
            sinU1 = tanU1 * cosU1;
        var sigma1 = Math.atan2(tanU1, cosAlpha1);
        var sinAlpha = cosU1 * sinAlpha1;
        var cosSqAlpha = 1 - sinAlpha * sinAlpha;
        var uSq = cosSqAlpha * (a * a - b * b) / (b * b);
        var A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
        var B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));

        var sigma = s / (b * A),
            sigmaP = 2 * Math.PI;
        while (Math.abs(sigma - sigmaP) > 1e-12) {
            var cos2SigmaM = Math.cos(2 * sigma1 + sigma);
            var sinSigma = Math.sin(sigma);
            var cosSigma = Math.cos(sigma);
            var deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
                B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
            sigmaP = sigma;
            sigma = s / (b * A) + deltaSigma;
        }

        var tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
        var lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
            (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp));
        var lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1);
        var C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
        var L = lambda - (1 - C) * f * sinAlpha *
            (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));

        var revAz = Math.atan2(sinAlpha, -tmp); // final bearing

        var lngLatObj = {
            lng: lon1 + util.mapNumberUtil.deg(L),
            lat: util.mapNumberUtil.deg(lat2)
        }
        return lngLatObj;
    },
    getDateFormat(value, dateformat, def) {
        if (value && dateformat) {
            let reg = /(\d{4})\S(\d{1,2})\S(\d{1,2})[\S\s](\d{1,2}):(\d{1,2}):(\d{1,2})/;
            let regdate = /(\d{4})\S(\d{1,2})\S(\d{1,2})/;
            if (reg.test(value) && value.toString().length < 20) {
                let result = value.match(reg);
                dateformat = dateformat.replace("yyyy", result[1]); //代表年
                dateformat = dateformat.replace("MM", result[2]); //代表月
                dateformat = dateformat.replace("dd", result[3]); //代表日
                if (dateformat.indexOf("hh") > -1) {
                    dateformat = dateformat.replace("hh", result[4]); //代表时
                } else {
                    dateformat = dateformat.replace("HH", result[4]); //代表时
                }
                dateformat = dateformat.replace("mm", result[5]); //代表分
                dateformat = dateformat.replace("ss", result[6]); //代表秒
                if (dateformat === "diff") {
                    return zjs.getDateDiff(result[1] + "/" + result[2] + "/" + result[3] + " " + result[4] + ":" + result[5] + ":" + result[6]);
                }
                return dateformat;
            } else if (regdate.test(value) && value.toString().length < 20) {
                let result = value.match(regdate);
                dateformat = dateformat.replace("yyyy", result[1]); //代表年
                dateformat = dateformat.replace("MM", result[2]); //代表月
                dateformat = dateformat.replace("dd", result[3]); //代表日 
                if (dateformat == "diff") {
                    return getDateDiff(result[1] + "/" + result[2] + "/" + result[3] + "");
                }
                return dateformat;
            }
        } else {
            if (def) value = def;
        }
        return value;
    },
    //取当前时间返回年月日
    getNow(dateformat, noZero, t) {
        let d = new Date();
        if (t) d = new Date(t);
        if (!dateformat) dateformat = "yyyy-MM-dd";
        dateformat = dateformat.replace("yyyy", d.getFullYear()); //代表年
        dateformat = dateformat.replace("MM", noZero ? (d.getMonth() + 1) : (d.getMonth() > 8 ? d.getMonth() + 1 : "0" + (d.getMonth() + 1))); //代表月
        dateformat = dateformat.replace("dd", noZero ? d.getDate() : (d.getDate() > 9 ? d.getDate() : "0" + d.getDate())); //代表日   
        if (dateformat.indexOf("hh") > -1) {
            dateformat = dateformat.replace("hh", noZero ? d.getHours() : (d.getHours() > 9 ? d.getHours() : "0" + d.getHours())); //代表时
        } else {
            dateformat = dateformat.replace("HH", noZero ? d.getHours() : (d.getHours() > 9 ? d.getHours() : "0" + d.getHours())); //代表时
        }
        dateformat = dateformat.replace("mm", noZero ? d.getMinutes() : (d.getMinutes() > 9 ? d.getMinutes() : "0" + d.getMinutes())); //代表分d.getMinutes()
        dateformat = dateformat.replace("ss", noZero ? d.getSeconds() : (d.getSeconds() > 9 ? d.getSeconds() : "0" + d.getSeconds())); //代表秒d.getSeconds()
        let week = d.getDay();
        let day = "";
        if (week == 0)
            day = "日";
        else if (week == 1)
            day = "一";
        else if (week == 2)
            day = "二";
        else if (week == 3)
            day = "三";
        else if (week == 4)
            day = "四";
        else if (week == 5)
            day = "五";
        else if (week == 6)
            day = "六";
        dateformat = dateformat.replace("weekday", day);
        return dateformat;
    },
    //时间戳转日期
    getTimeDate(t, dateformat) {
        return util.getNow(dateformat, false, t);
    },
    htmlDecode(value) {
        if (typeof value == "string") value = value.replace(new RegExp("&nbsp;;", 'g'), "&nb-sp;");
        var frameDiv = document.createElement("div");
        frameDiv.innerHTML = value;
        value = frameDiv.innerText;
        value = value.replace(new RegExp("&nb-sp;", 'g'), "&nbsp;");
        if (typeof value == "string") {
            var dec = ["&ldquo;-“", "&rdquo;-”", "&lsquo;-‘", "&rsquo;-’", "&quot;-\"", "&#39;-'", "&acute;-´", "&lt;-<", "&gt;->", "&laquo;-«", "&raquo;-»", "&lsaquo;-‹", "&rsaquo;-›", "&crarr;-↵"];
            for (var i in dec) {
                var decA = dec[i].split("-");
                if (value.indexOf(decA[0]) > -1) value = value.replace(new RegExp(decA[0], 'g'), decA[1]);
            }
        }
        return value;
    },
    blobDownload(data, filename) {
        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
            var csvData = new Blob([data], {
                type: 'text/csv'
            });
            window.navigator.msSaveOrOpenBlob(csvData, filename);
        } else {
            let url = window.URL.createObjectURL(data)
            let link = document.createElement('a')
            link.style.display = 'none'
            link.href = url
            link.setAttribute('download', filename)
            link.setAttribute('target', "_blank")
            document.body.appendChild(link)
            link.click()
            link.remove();
            window.URL.revokeObjectURL(url);
        }
    },
    isInteger(obj) {
        return Math.floor(obj) === obj
    },
    toInteger(floatNum) {
        var ret = {
            times: 1,
            num: 0
        };
        if (util.isInteger(floatNum)) {
            ret.num = floatNum;
            return ret
        }
        var strfi = floatNum + '';
        var dotPos = strfi.indexOf('.');
        var len = strfi.substr(dotPos + 1).length;
        var times = Math.pow(10, len);
        var intNum = parseInt(floatNum * times + 5, 10);
        ret.times = times;
        ret.num = intNum;
        return ret
    },
    operation(a, b, op) {
        var o1 = util.toInteger(a);
        var o2 = util.toInteger(b);
        var n1 = o1.num;
        var n2 = o2.num;
        var t1 = o1.times;
        var t2 = o2.times;
        var max = t1 > t2 ? t1 : t2;
        var result = null;
        switch (op) {
            case 'add':
                if (t1 === t2) { // 两个小数位数相同
                    result = n1 + n2
                } else if (t1 > t2) { // o1 小数位 大于 o2
                    result = n1 + n2 * (t1 / t2)
                } else { // o1 小数位 小于 o2
                    result = n1 * (t2 / t1) + n2
                }
                return result / max;
            case 'subtract':
                if (t1 === t2) {
                    result = n1 - n2
                } else if (t1 > t2) {
                    result = n1 - n2 * (t1 / t2)
                } else {
                    result = n1 * (t2 / t1) - n2
                }
                return result / max;
            case 'multiply':
                result = (n1 * n2) / (t1 * t2);
                return result;
            case 'divide':
                result = (n1 / n2) * (t2 / t1);
                return result
        }
    },
    add(a, b) { //加
        return util.operation(a, b, 'add')
    },
    subtract(a, b) { //减
        return util.operation(a, b, 'subtract')
    },
    multiply(a, b) { //乘
        return util.operation(a, b, 'multiply')
    },
    divide(a, b) { //除
        return util.operation(a, b, 'divide')
    },
    closeTabActive(that) {
        that.$parent.$parent.$children[2].closeTabActive();
    },
    closeTab(that, path) {
        that.$parent.$parent.$children[2].closeTab({
            path
        });
    },

    // 级联选择器回显，支持多个值
    getNamesFromTreeData(arry, treeData, showLevel) {
        // id(必传) 数组
        // 数据列表(必传)
        // 展示第几层的名称(不必传) start--第一层(默认)  end--最后一层  all--全展示
        var namesArry = [],
            namesStr = "";
        for (var i in arry) {
            if (typeof (arry[i]) == "object") { //多个值 [['123','aaa'],['456','bbb']]
                namesArry.push(this.matchNames(arry[i], treeData, showLevel));
            } else { //单个值 ['123','aaa'] 或 "'123','aaa'"
                namesStr = this.matchNames(arry, treeData, showLevel);
            }
        }
        if (namesArry.length > 0) namesStr = namesArry.join("，");
        return namesStr;
    },
    matchNames(value, childrenData, showLevel) {
        var arry = [],
            result = [],
            resultStr = "";
        var depth = 0;
        // 将值转为数组
        if (typeof (value) == 'string') {
            arry = value.indexOf(',') != -1 ? value.split(',') : [value];
        } else {
            arry = value;
        }

        function match(childrenData, depthN) {
            if (childrenData) {
                depth = depthN;
                var flag = 0;
                for (var j in childrenData) {
                    if (arry[depthN] == childrenData[j].id) {
                        flag++;
                        result.push(childrenData[j].name);
                    }

                    if (flag > 0) {
                        if (childrenData[j].children) {
                            depthN++;
                            match(childrenData[j].children, depthN);
                        } else {
                            break;
                        }
                    }
                }
                // 展示层级
                if (showLevel == "end") {
                    resultStr = result[result.length - 1];
                } else if (showLevel == "all") {
                    resultStr = result.join("-");
                } else {
                    resultStr = result[0];
                }
            }
            return resultStr;
        }

        return match(childrenData, depth);
    },
    /**
     * AES加密（CBC模式，需要偏移量）
     * @param data
     * @returns {*}
     */
    aesEncrypt(data) {
        var key = CryptoJS.enc.Utf8.parse("dW5uR,Yml#y%PeLG");
        var iv = CryptoJS.enc.Utf8.parse("Be*Kn0xJ&XHc(Jl0");
        var secretData = CryptoJS.enc.Utf8.parse(data);
        var encrypted = CryptoJS.AES.encrypt(
            secretData,
            key, {
                iv: iv,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            }
        );
        return encrypted.toString();
    },
    /**
     * AES解密（CBC模式，需要偏移量）
     * @param data
     * @returns {*}
     */
    aesDecrypt(data) {
        var key = CryptoJS.enc.Utf8.parse("dW5uR,Yml#y%PeLG");
        var iv = CryptoJS.enc.Utf8.parse("Be*Kn0xJ&XHc(Jl0");
        var decrypt = CryptoJS.AES.decrypt(
            data,
            key, {
                iv: iv,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            }
        );
        return CryptoJS.enc.Utf8.stringify(decrypt).toString();
    },

};
export default util